package com.gj.xxl.job.core.thread;

import com.gj.xxl.job.core.biz.model.TriggerParam;
import com.gj.xxl.job.core.executor.GjJobSpringExecutor;
import com.gj.xxl.job.core.handler.MethodJobHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class JobThread extends Thread {

    private static Logger logger = LoggerFactory.getLogger(JobThread.class);

    private Integer jobId;

    private LinkedBlockingQueue<TriggerParam> jobQueue;

    //线程空闲的次数，基于这个实现空闲线程的销毁
    private int idleTime = 0;

    private volatile boolean toStop = false;

    private volatile boolean running = false;

    public LinkedBlockingQueue<TriggerParam> getJobQueue() {
        return jobQueue;
    }

    public JobThread(Integer jobId) {
        this.jobId = jobId;
        this.jobQueue = new LinkedBlockingQueue<>();
    }

    public boolean jobThreadRunning() {
        if (running || jobQueue.size() > 0) {
            return true;
        }
        return false;
    }


    @Override
    public void run() {
        while (!toStop) {
            running = false;
            idleTime++;
            try {
                TriggerParam triggerParam = jobQueue.poll(3, TimeUnit.SECONDS);
                if (triggerParam != null) {
                    running = true;
                    idleTime = 0;
                    MethodJobHandler jobHandler = GjJobSpringExecutor.getMethodJobHandler(triggerParam);
                    if (triggerParam.getExecutorTimeout() > 0) {
                        Thread futureThread = null;
                        try {
                            FutureTask<Boolean> futureTask = new FutureTask<>(() -> {
                                logger.info("jobId = " + triggerParam.getJobId() + " 被线程 = " + Thread.currentThread().getName() + " 执行了");
                                jobHandler.invoke();
                                return true;
                            });
                            futureThread = new Thread(futureTask);
                            futureThread.start();
                            Boolean result = futureTask.get(triggerParam.getExecutorTimeout(), TimeUnit.SECONDS);
                        } catch (TimeoutException e) {
                            //任务执行超时了
                            logger.info("jobId = " + triggerParam.getJobId() + " 被线程 = " + Thread.currentThread().getName() + " 执行，但是超时了！！！！");
                        } finally {
                            futureThread.interrupt();
                        }
                    } else {
                        jobHandler.invoke();
                    }
                } else {
                    if (idleTime > 30) {
                        if (jobQueue.size() == 0) {
                            logger.info(Thread.currentThread().getName() + " 空闲线程被销毁了");
                            GjJobSpringExecutor.removeJobThread(jobId);
                        }
                    }
                }
            } catch (Throwable e) {
                if (toStop) {
                    logger.info(">>>>>>>>>>>>>>>>> jobThread: {} toStop", Thread.currentThread());
                }
            }
        }
    }

    public void toStop() {
        this.toStop = true;
    }

}

